home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
pmf300.zip
/
DSKIM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-16
|
25KB
|
693 lines
/*
dskim.c
disk handling routines for pmfloppy.c
G. Bryant, 1990,1993
Delta Music Systems
Released to the public domain
Change Log
5-Feb-93 Port to OS/2 2.0-C Set/2
*/
#define INCL_DOSERRORS
#define INCL_DOSPROCESS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSSESMGR
#define INCL_DOSMISC
#define INCL_DOSFILEMGR
#include <os2.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pmfloppy.h"
#include "DskIm.h"
/* Global variables ------------------------------------------------------ */
// PM vbls
extern HWND hWndFrame ;
// user response vbls
extern DskImage ImageBuffers[NUM_IMAGES];
// Thread variables
extern ThreadContext tcThBufs[NUM_THREADS];
// "local" global vbls
BYTE _lockCmd; /* Used with [un]lockdrive macros */
ULONG _fmtData; /* Used with DSK_FORMATVERIFY */
// Global function prototypes
VOID _System readsource(ULONG);
VOID _System writetarget(ULONG);
VOID _System LoadImage(ULONG);
VOID _System SaveImage(ULONG);
VOID _System CompImages(ULONG);
// local function prototypes
SHORT fmttbl_bytessec(USHORT, ULONG *);
SHORT bspblkcmp(BSPBLK *, BSPBLK *);
VOID ThreadErrorHandler(USHORT, ULONG, HFILE);
/* Code ------------------------------------------------------------------ */
// Read source disk into memory
//
// when done track data is in huge space starting with selector
// stored in the global
// sets global variables:
// tcThBufs
// ImageBuffers
//
VOID readsource(ULONG curTh)
{
BYTE parmCmd = 1;
USHORT trk, hd, cyl;
HFILE dHandle;
ULONG result;
static CHAR szdrive[] = "A:";
ULONG sourceBytes; /* # bytes on source disk */
USHORT sourceTracks; /* # tracks on source disk */
ULONG bytesPerTrack;
USHORT curBuff;
ULONG pLen;
ULONG dLen;
PBYTE DskBuf; // pointer to track data
curBuff = tcThBufs[curTh].ImageNumber;
tcThBufs[curTh].ErrorCode = 0;
/* If this isn't the first time here, free memory from last time first */
if (ImageBuffers[curBuff].Percent == 100)
{
free(ImageBuffers[curBuff].DskSel);
free(ImageBuffers[curBuff].DskLayout);
}
/* Get source disk parameters */
DosError(FERR_DISABLEHARDERR);
szdrive[0] = ImageBuffers[curBuff].DriveID[0];
tcThBufs[curTh].ErrorCode = DosOpen(szdrive,
&dHandle,
&result,
0,
FILE_NORMAL,
OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
OPENFLAGS,
NULL);
if (tcThBufs[curTh].ErrorCode)
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
pLen = sizeof _lockCmd;
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_LOCKDRIVE,
&_lockCmd, sizeof _lockCmd, &pLen,
NULL, 0, NULL);
if (tcThBufs[curTh].ErrorCode)
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
pLen = sizeof parmCmd;
dLen = sizeof ImageBuffers[curBuff].DskParms;
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_GETDEVICEPARAMS,
&parmCmd, sizeof parmCmd, &pLen,
&ImageBuffers[curBuff].DskParms,
sizeof ImageBuffers[curBuff].DskParms,
&dLen);
if (!tcThBufs[curTh].ErrorCode)
{
/* Set all the informational variables and build a track layout table
** for use with the following sector reads.
*/
sourceBytes = (ULONG)(ImageBuffers[curBuff].DskParms.usBytesPerSector) *
(ULONG)(ImageBuffers[curBuff].DskParms.cSectors);
sourceTracks = ImageBuffers[curBuff].DskParms.cSectors /
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
bytesPerTrack = ImageBuffers[curBuff].DskParms.usBytesPerSector *
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
ImageBuffers[curBuff].usLayoutSize = sizeof(TRACKLAYOUT) +
((2 * sizeof(USHORT)) *
(ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
if (ImageBuffers[curBuff].DskLayout =
(PTRACKLAYOUT)malloc(ImageBuffers[curBuff].usLayoutSize * sizeof(BYTE)))
{
ImageBuffers[curBuff].DskLayout->bCommand = 1;
ImageBuffers[curBuff].DskLayout->usFirstSector = 0;
ImageBuffers[curBuff].DskLayout->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
for (trk = 0; trk < ImageBuffers[curBuff].DskParms.usSectorsPerTrack; trk++)
{
ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorNumber = trk+1;
ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorSize =
ImageBuffers[curBuff].DskParms.usBytesPerSector;
}
}
else
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
// Allocate memory to hold the track data
if (!(ImageBuffers[curBuff].DskSel = (PBYTE)malloc(sourceBytes)))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf = ImageBuffers[curBuff].DskSel;
// For each track, set the pointer and read the sector into it
for (trk = 0, cyl = 0;
trk < sourceTracks;
trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++)
{
ImageBuffers[curBuff].DskLayout->usCylinder = cyl;
for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++)
{
ImageBuffers[curBuff].Percent =
(USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
WinPostMsg(hWndFrame,UM_STATUS,MPFROMLONG(curTh),0);
ImageBuffers[curBuff].DskLayout->usHead = hd;
pLen = sizeof (TRACKLAYOUT);
dLen = bytesPerTrack;
if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_READTRACK,
ImageBuffers[curBuff].DskLayout,sizeof (TRACKLAYOUT),&pLen,
DskBuf, bytesPerTrack, &dLen))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf += bytesPerTrack;
}
}
ImageBuffers[curBuff].Percent = 100;
WinPostMsg(hWndFrame,UM_DONE,MPFROMLONG(curTh),0);
}
else
{
WinPostMsg(hWndFrame,UM_ERROR,MPFROMLONG(curTh),0);
}
if (dHandle) DosClose(dHandle);
pLen = sizeof _lockCmd;
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_UNLOCKDRIVE,
&_lockCmd, sizeof _lockCmd, &pLen,
NULL, 0, NULL);
DosError(FERR_ENABLEHARDERR);
DosExit(EXIT_THREAD,0);
} // readsource
/* --- Translate bytes per sector into 0-3 code ---
** the four sector sizes listed below are alluded to in the OS/2
** docs however only 512 byte sectors are allowed under OS/2 1.x
** returns the code or -1 and sets DiskError
*/
SHORT fmttbl_bytessec(USHORT bytesPerSec, ULONG *DiskError)
{
*DiskError = NO_ERROR;
switch (bytesPerSec)
{
case 128: return 0;
case 256: return 1;
case 512: return 2;
case 1024: return 3;
}
*DiskError = ERROR_BAD_FORMAT;
return -1;
}
/* --- write information read by readsource() onto target disk ---
** parameter is drive handle as returned by opendrive()
** checks the target disk, if it's the same format as the source
** or not formatted at all, write the information contained in
** DskBuffer formatting if neccessary.
** returns 0 if successful else errorcode
**
*/
VOID writetarget(ULONG curTh)
{
BYTE _parmCmd = 1;
PTRACKFORMAT trkfmt;
USHORT sizeofTrkfmt;
USHORT i, trk, hd, cyl, needFormat = FALSE;
HFILE dHandle;
ULONG result;
static CHAR szdrive[] = "A:";
BSPBLK targetParms;
ULONG bytesPerTrack;
USHORT sourceTracks; /* # tracks on source disk */
USHORT curBuff;
ULONG pLen, dLen;
PBYTE DskBuf; // huge pointer to track data
curBuff = tcThBufs[curTh].ImageNumber;
tcThBufs[curTh].ErrorCode = 0;
/* Get source disk parameters */
DosError(FERR_DISABLEHARDERR);
szdrive[0] = ImageBuffers[curBuff].DriveID[0];
tcThBufs[curTh].ErrorCode = DosOpen(szdrive,
&dHandle,
&result,
0,
FILE_NORMAL,
OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
OPENFLAGS,
NULL);
if (tcThBufs[curTh].ErrorCode)
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
pLen = sizeof _lockCmd;
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_LOCKDRIVE,
&_lockCmd, sizeof _lockCmd, &pLen,
NULL, 0, NULL);
if (tcThBufs[curTh].ErrorCode)
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
/* Get target disk parameters */
pLen = sizeof _parmCmd;
dLen = sizeof (BSPBLK);
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_GETDEVICEPARAMS,
&_parmCmd, sizeof (BYTE), &pLen,
&targetParms,sizeof (BSPBLK) , &dLen);
if ((tcThBufs[curTh].ErrorCode == ERROR_READ_FAULT) &&
(ImageBuffers[curBuff].FormatOptions == IDD_WRF_NEVER))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
if (((tcThBufs[curTh].ErrorCode == ERROR_READ_FAULT) &&
(ImageBuffers[curBuff].FormatOptions == IDD_WRF_MAYBE)) ||
(ImageBuffers[curBuff].FormatOptions == IDD_WRF_ALWAYS))
{
/* If the disk needs formatting we build a format table for it based
** on the source disk.
*/
needFormat = TRUE;
tcThBufs[curTh].ErrorCode = 0;
// Set all the informational variables needed for formatting
sizeofTrkfmt = sizeof(TRACKFORMAT) +
((4 * sizeof(BYTE)) *
(ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
if ((trkfmt = (PTRACKFORMAT)malloc(sizeofTrkfmt * sizeof(BYTE))) == NULL)
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
trkfmt->bCommand = 1;
trkfmt->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
for (trk = 0; trk < trkfmt->cSectors; trk++)
{
trkfmt->FormatTable[trk].idSector = (BYTE)(trk+1);
trkfmt->FormatTable[trk].bBytesSector =
fmttbl_bytessec(ImageBuffers[curBuff].DskParms.usBytesPerSector,
&(tcThBufs[curTh].ErrorCode));
}
}
else if (!tcThBufs[curTh].ErrorCode)
/* Else if no other error, make sure that the target disk is the same
** format as the source.
*/
if (bspblkcmp(&(ImageBuffers[curBuff].DskParms), &targetParms))
tcThBufs[curTh].ErrorCode = DSKIM_ERROR_WRONG_FORMAT;
sourceTracks = ImageBuffers[curBuff].DskParms.cSectors /
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
bytesPerTrack = ImageBuffers[curBuff].DskParms.usBytesPerSector *
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
DskBuf = ImageBuffers[curBuff].DskSel;
if (!tcThBufs[curTh].ErrorCode)
{
for (trk = 0, cyl = 0; trk < sourceTracks; trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++)
{
ImageBuffers[curBuff].DskLayout->usCylinder = cyl;
for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++)
{
ImageBuffers[curBuff].Percent =
(USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
WinPostMsg(hWndFrame,UM_STATUS, MPFROMLONG(curTh),0);
ImageBuffers[curBuff].DskLayout->usHead = hd;
if (needFormat)
{
trkfmt->usHead = hd;
trkfmt->usCylinder = cyl;
for (i = 0; i < trkfmt->cSectors; i++)
{
trkfmt->FormatTable[i].bHead = (BYTE)hd;
trkfmt->FormatTable[i].bCylinder = (BYTE)cyl;
}
pLen = sizeof (TRACKFORMAT);
dLen = sizeof _fmtData;
if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_FORMATVERIFY,
trkfmt,sizeof (TRACKFORMAT),&pLen,
&_fmtData,sizeof (ULONG),&dLen))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
}
if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_WRITETRACK,
ImageBuffers[curBuff].DskLayout,sizeof (TRACKLAYOUT),&pLen,
DskBuf, bytesPerTrack, &dLen))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf += bytesPerTrack;
}
}
ImageBuffers[curBuff].Percent = 100;
if (needFormat) free(trkfmt);
WinPostMsg(hWndFrame,UM_DONE,MPFROMLONG(curTh),0);
}
else
{
WinPostMsg(hWndFrame,UM_ERROR,MPFROMLONG(curTh),0);
}
if (dHandle) DosClose(dHandle);
pLen = sizeof _lockCmd;
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_UNLOCKDRIVE,
&_lockCmd, sizeof _lockCmd, &pLen,
NULL, 0, NULL);
DosError(FERR_ENABLEHARDERR);
DosExit(EXIT_THREAD,0);
} //writetarget
/* --- compare two BSPBLK structures ---
** returns 0 if both are the same except for possibly the
** abReserved field, else returns non-zero.
*/
SHORT bspblkcmp(BSPBLK *blk1, BSPBLK *blk2) {
BSPBLK tmp1, tmp2;
tmp1 = *blk1;
tmp2 = *blk2;
memset(tmp1.abReserved, 0, 6);
memset(tmp2.abReserved, 0, 6);
return memcmp(&tmp1, &tmp2, sizeof(BSPBLK));
}
VOID ThreadErrorHandler(USHORT Msg, ULONG curTh, HFILE dHandle)
{
ULONG pLen = sizeof _lockCmd;
WinPostMsg(hWndFrame,Msg,MPFROMLONG(curTh),0);
if (dHandle) DosClose(dHandle);
tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
IOCTL_DISK,
DSK_UNLOCKDRIVE,
&_lockCmd, sizeof _lockCmd, &pLen,
NULL, 0, NULL);
DosError(FERR_ENABLEHARDERR);
DosExit(EXIT_THREAD, 0);
}
// Load the disk image.
//
// Note that although it is not used here, we will create the layout
// table as it is needed by writetarget
//
VOID LoadImage(ULONG curTh) {
USHORT curBuff;
ULONG bytesPerTrack;
USHORT sourceTracks; // # tracks on source disk
ULONG sourceBytes; // # bytes on source disk
USHORT trk;
USHORT hd;
USHORT cyl;
HFILE dHandle;
ULONG result;
CHAR Header[] = "DskImage";
CHAR NewHead[9]; // must be size of header
PBYTE DskBuf; // huge pointer to track data
curBuff = tcThBufs[curTh].ImageNumber;
tcThBufs[curTh].ErrorCode = 0;
// If this isn't the first time here, free memory from last time first
if (ImageBuffers[curBuff].Percent == 100) {
free(ImageBuffers[curBuff].DskSel);
free(ImageBuffers[curBuff].DskLayout);
}
if (tcThBufs[curTh].ErrorCode = DosOpen(ImageBuffers[curBuff].FileName,
&dHandle,
&result,
0,
FILE_NORMAL,
OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
NULL))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
// read dskim header
if (tcThBufs[curTh].ErrorCode = DosRead(dHandle,&NewHead,sizeof NewHead,&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
if (strcmp(Header,NewHead)) {
tcThBufs[curTh].ErrorCode = DSKIM_ERROR_WRONG_FILE;
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
}
// read parameter block
if (tcThBufs[curTh].ErrorCode = DosRead(dHandle,
&ImageBuffers[curBuff].DskParms,
sizeof ImageBuffers[curBuff].DskParms,
&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
sourceBytes = (ULONG)(ImageBuffers[curBuff].DskParms.usBytesPerSector) *
(ULONG)(ImageBuffers[curBuff].DskParms.cSectors);
sourceTracks = ImageBuffers[curBuff].DskParms.cSectors /
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
bytesPerTrack = ImageBuffers[curBuff].DskParms.usBytesPerSector *
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
ImageBuffers[curBuff].usLayoutSize = sizeof(TRACKLAYOUT) +
((2 * sizeof(USHORT)) *
(ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
if (ImageBuffers[curBuff].DskLayout =
(PTRACKLAYOUT)malloc(ImageBuffers[curBuff].usLayoutSize * sizeof(BYTE))) {
ImageBuffers[curBuff].DskLayout->bCommand = 1;
ImageBuffers[curBuff].DskLayout->usFirstSector = 0;
ImageBuffers[curBuff].DskLayout->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
for (trk = 0; trk < ImageBuffers[curBuff].DskParms.usSectorsPerTrack; trk++) {
ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorNumber = trk+1;
ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorSize =
ImageBuffers[curBuff].DskParms.usBytesPerSector;
}
}
else
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
// Allocate memory to hold the track data
if (!(ImageBuffers[curBuff].DskSel = (PBYTE)malloc(sourceBytes)))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf = ImageBuffers[curBuff].DskSel;
// read disk data
for (trk = 0, cyl = 0;
trk < sourceTracks;
trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
ImageBuffers[curBuff].Percent =
(USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
WinPostMsg(hWndFrame,UM_STATUS, MPFROMLONG(curTh),0);
if (tcThBufs[curTh].ErrorCode = DosRead(dHandle,DskBuf,bytesPerTrack,&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf += bytesPerTrack;
}
}
ImageBuffers[curBuff].Percent = 100;
WinPostMsg(hWndFrame,UM_DONE,MPFROMLONG(curTh),0);
if (dHandle) DosClose(dHandle);
DosExit(EXIT_THREAD,0);
}
// Save the following fields
//
// BSPBLK DskParms
// PTRACKLAYOUT DskLayout
// USHORT usLayoutSize
VOID SaveImage(ULONG curTh) {
USHORT curBuff;
USHORT sourceTracks; // # tracks on source disk
ULONG bytesPerTrack;
USHORT trk;
USHORT hd;
USHORT cyl;
HFILE dHandle;
ULONG result;
ULONG FileSize;
CHAR Header[] = "DskImage";
PBYTE DskBuf; // huge pointer to track data
curBuff = tcThBufs[curTh].ImageNumber;
tcThBufs[curTh].ErrorCode = 0;
// calculate file size
sourceTracks = ImageBuffers[curBuff].DskParms.cSectors /
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
bytesPerTrack = ImageBuffers[curBuff].DskParms.usBytesPerSector *
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
FileSize = (sourceTracks * bytesPerTrack) +
sizeof Header +
sizeof ImageBuffers[curBuff].DskParms;
if (tcThBufs[curTh].ErrorCode = DosOpen(ImageBuffers[curBuff].FileName,
&dHandle,
&result,
FileSize,
FILE_NORMAL,
OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
0L))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
// write dskim header
if (tcThBufs[curTh].ErrorCode = DosWrite(dHandle,&Header,sizeof Header,&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
// write parameter block
if (tcThBufs[curTh].ErrorCode = DosWrite(dHandle,
&ImageBuffers[curBuff].DskParms,
sizeof ImageBuffers[curBuff].DskParms,
&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf = ImageBuffers[curBuff].DskSel;
// write disk data
for (trk = 0, cyl = 0;
trk < sourceTracks;
trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
ImageBuffers[curBuff].Percent =
(USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
WinPostMsg(hWndFrame,UM_STATUS, MPFROMLONG(curTh),0);
if (tcThBufs[curTh].ErrorCode = DosWrite(dHandle,DskBuf,bytesPerTrack,&result))
ThreadErrorHandler(UM_ERROR, curTh, dHandle);
DskBuf += bytesPerTrack;
}
}
ImageBuffers[curBuff].Percent = 100;
WinPostMsg(hWndFrame,UM_DONE,MPFROMLONG(curTh),0);
if (dHandle) DosClose(dHandle);
DosExit(EXIT_THREAD,0);
}
VOID CompImages(ULONG curTh) {
USHORT curBuff;
USHORT compBuff;
USHORT bytesPerTrack; // Bytes per track
USHORT sourceTracks; // # tracks on source disk
USHORT trk;
USHORT hd;
USHORT cyl;
HFILE hf = NULLHANDLE; // only needed for error handling
PBYTE DskBuf1; // huge pointer to track data
PBYTE DskBuf2; // huge pointer to track data
curBuff = tcThBufs[curTh].ImageNumber;
compBuff = tcThBufs[curTh].CompNumber;
tcThBufs[curTh].ErrorCode = 0;
// compare BPB
if (memcmp(&(ImageBuffers[curBuff].DskParms),
&(ImageBuffers[compBuff].DskParms),
sizeof(BSPBLK))) {
ThreadErrorHandler(UM_COMPERR, curTh, hf);
DosExit(EXIT_THREAD,0);
}
// compare data
sourceTracks = ImageBuffers[curBuff].DskParms.cSectors /
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
bytesPerTrack = ImageBuffers[curBuff].DskParms.usBytesPerSector *
ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
DskBuf1 = ImageBuffers[curBuff].DskSel;
DskBuf2 = ImageBuffers[compBuff].DskSel;
for (trk = 0, cyl = 0;
trk < sourceTracks;
trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++)
{
for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++)
{
ImageBuffers[curBuff].Percent =
(USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
WinPostMsg(hWndFrame,UM_STATUS, MPFROMLONG(curTh),0);
if (memcmp(DskBuf1,DskBuf2,bytesPerTrack))
{
ThreadErrorHandler(UM_COMPERR, curTh, hf);
DosExit(EXIT_THREAD,0);
}
DskBuf1 += bytesPerTrack;
DskBuf2 += bytesPerTrack;
}
}
ImageBuffers[curBuff].Percent = 100;
WinPostMsg(hWndFrame,UM_COMPOK,MPFROMLONG(curTh),0);
DosExit(EXIT_THREAD,0);
} // CompImages